﻿// The MIT License (MIT)

// Copyright (c) 2014 Md Ishtiaque Shahrier (Exico software solutions www.exico.ca)

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.Web.Mvc;
using ExicoSoftwareSolutions.WebTools.MvcPagination.Classes;

namespace ExicoSoftwareSolutions.WebTools.MvcPagination
{
    public class DefaultPager : APager
    {

        public DefaultPager(int TotalItems, int ItemsPerPage, PagerOptions options)
            : base(TotalItems, ItemsPerPage, options)
        {
        }

        public DefaultPager(int TotalItems, int ItemsPerPage)
            : base(TotalItems, ItemsPerPage)
        {
        }

        protected override void Execute()
        {
            if (GetTotalPages() <= 1 && !this.Options.ShowEvenOnlyOnePage) return;

            Dictionary<string, string> html = new Dictionary<string, string>();

            this.GetFirstLinkPart = html["f"] = null;
            this.GetLastLinkPart = html["l"] = null;
            this.GetPreviousLinkPart = html["p"] = null;
            this.GetNextLinkPart = html["n"] = null;
            this.GetSummaryPart = html["s"] = null;

            if (Options.ShowSummary)
            {
                this.GetSummaryPart = html["s"] = String.Format(Options.SummaryFormat, this.CurrentPageNumber(), this.GetTotalPages());
            }

            if (this.Options.ShowFirstAndLast)
            {
                this.GetFirstLinkPart = html["f"] = new FirstLink(this, this.Options.FirstText) { Class = "firstlast" }.Render();
                this.GetLastLinkPart = html["l"] = new LastLink(this, this.Options.LastText) { Class = "firstlast" }.Render();
            }
            if (this.Options.ShowNextAndPrev)
            {
                this.GetPreviousLinkPart = html["p"] = new PrevLink(this, this.Options.PrevText) { Class = "nextprev" }.Render();
                this.GetNextLinkPart = html["n"] = new NextLink(this, this.Options.NextText) { Class = "nextprev" }.Render();
            }

            //TODO : think about it later
            int from = this.Options.ShowFirstAndLast ? 2 : 1;
            int to = this.Options.ShowFirstAndLast ? this.GetTotalPages() - 1 : this.GetTotalPages();

            IList<string> links = new List<string>();

            int halfPage = this.Options.NumberOfPagesToDisplay / 2;
            int startPage = this.CurrentPageNumber() - halfPage;
            if (this.CurrentPageNumber() + halfPage > this.GetTotalPages())
            {
                startPage = this.GetTotalPages() - this.Options.NumberOfPagesToDisplay + 1;
            }
            if (startPage <= 0) startPage = 1;
            int pagePrint = 1;
            bool started = false;

            for (int i = 1; i <= this.GetTotalPages(); i++)
            {
                bool display = false;
                if (this.Options.NumberOfPagesToDisplay > 0)
                {
                    if (!started && i == startPage)
                    {
                        started = true;
                    }
                    if (started && pagePrint <= this.Options.NumberOfPagesToDisplay)
                    {
                        display = true;
                        pagePrint++;
                    }


                }
                if (this.Options.NumberOfPagesToDisplay <= 0 || display)
                {
                    links.Add(new NumberedLink(this, i).Render());
                }
            }

            this.GetNumberedLinkPart = html["a"] = String.Join("", links.ToArray());//all other links



        }

        //rendering style
        public virtual string Render()
        {
            this.Execute();
            List<string> final = new List<string>();
            final.Add(string.Format("<span class='pageFirstLink'>{0}</span>", this.GetFirstLinkPart ?? "") ?? "");
            final.Add(string.Format("<span class='pagePrevLink'>{0}</span>", this.GetPreviousLinkPart ?? "") ?? "");
            final.Add(string.Format("<span class='pageLinks'>{0}</span>", this.GetNumberedLinkPart ?? "") ?? "");
            final.Add(string.Format("<span class='pageNextLink'>{0}</span>", this.GetNextLinkPart ?? "") ?? "");
            final.Add(string.Format("<span class='pageLastLink'>{0}</span>", this.GetLastLinkPart ?? "") ?? "");
            final.Add(string.Format("<span class='pageSummary'>{0}</span>", this.GetSummaryPart ?? "") ?? "");


            return string.Format("<div class='{0}' >{1}</div>",
                                  this.Options.WrapperDivClass,
                                  string.Join("", final.ToArray())
                                );
        }
        public override string GetFirstLinkPart { get; protected set; }
        public override string GetLastLinkPart { get; protected set; }
        public override string GetPreviousLinkPart { get; protected set; }
        public override string GetNextLinkPart { get; protected set; }
        public override string GetNumberedLinkPart { get; protected set; }
        public override string GetSummaryPart { get; protected set; }
    }
}
